/* Copyright (c) 2006, 2009, Carl Burch. License information is located in the
 * com.cburch.logisim.Main source code and at www.cburch.com/logisim/. */
 
package com.cburch.draw.model;

import com.cburch.logisim.data.Attribute;
import com.cburch.logisim.data.AttributeEvent;
import com.cburch.logisim.data.AttributeListener;
import com.cburch.logisim.data.AttributeSet;
import com.cburch.logisim.collections.EventSourceWeakSupport;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public class DrawingAttributeSet implements AttributeSet, Cloneable {
    private EventSourceWeakSupport listeners;
    private List attrs;
    private List values;
    private List selectedAttrs;
    private List selectedView;
    
    public DrawingAttributeSet() {
        listeners = new EventSourceWeakSupport();
        attrs = DrawingAttribute.ATTRS_ALL;
        values = DrawingAttribute.DEFAULTS_ALL;
        selectedAttrs = new ArrayList();
        selectedAttrs.addAll(attrs);
        selectedView = Collections.unmodifiableList(selectedAttrs);
    }
    
    public void setAttributes(List attrs) {
        List selected = selectedAttrs;
        if(!selected.equals(attrs)) {
            selected.clear();
            selected.addAll(attrs);
            AttributeEvent e = new AttributeEvent(this);
            for(Iterator it = listeners.iterator(); it.hasNext(); ) {
                AttributeListener l = (AttributeListener) it.next();
                l.attributeListChanged(e);
            }
        }
    }
    
    public void addAttributeListener(AttributeListener l) {
        listeners.add(l);
    }

    public void removeAttributeListener(AttributeListener l) {
        listeners.remove(l);
    }
    
    public Object clone() {
        try {
            DrawingAttributeSet ret = (DrawingAttributeSet) super.clone();
            ret.listeners = new EventSourceWeakSupport();
            ret.values = new ArrayList(this.values);
            ret.selectedAttrs = new ArrayList(this.selectedAttrs);
            return ret;
        } catch(CloneNotSupportedException e) {
            return null;
        }
    }
    
    public List getAttributes() {
        return selectedView;
    }

    public boolean containsAttribute(Attribute attr) {
        return selectedAttrs.contains(attr);
    }
    
    public Attribute getAttribute(String name) {
        for(Iterator it = selectedAttrs.iterator(); it.hasNext(); ) {
            Attribute attr = (Attribute) it.next();
            if(attr.getName().equals(name)) return attr;
        }
        return null;
    }

    public boolean isReadOnly(Attribute attr) {
        return false;
    }
    
    public void setReadOnly(Attribute attr, boolean value) {
        throw new UnsupportedOperationException("setReadOnly");
    }
    
    public Object getValue(Attribute attr) {
        Iterator ait = attrs.iterator();
        Iterator vit = values.iterator();
        while(ait.hasNext()) {
            Object a = ait.next();
            Object v = vit.next();
            if(a.equals(attr)) return v;
        }
        return null;
    }

    public void setValue(Attribute attr, Object value) {
        Iterator ait = attrs.iterator();
        ListIterator vit = values.listIterator();
        while(ait.hasNext()) {
            Object a = ait.next();
            vit.next();
            if(a.equals(attr)) {
                vit.set(value);
                AttributeEvent e = new AttributeEvent(this, attr, value);
                for(Iterator it = listeners.iterator(); it.hasNext(); ) {
                    AttributeListener l = (AttributeListener) it.next();
                    l.attributeValueChanged(e);
                }
                return;
            }
        }
        throw new IllegalArgumentException(attr.toString());
    }
}
